import zipfile, os,gzip, bz2,shutil,lzma ,py7zr
name = "wackyfile.7z"                # 起始文件
outdir = 'wackyfile_list'
os.makedirs(outdir, exist_ok=True)    # 建立解压目录（不会报已存在的错）
ARCH_EXTS = {'.zip', '.gz', '.bz2', '.xz', '.7z'}
def extract_zip(filename,outdir):
    with zipfile.ZipFile(filename, 'r') as z:   # 打开当前这一层 zip
        z.extractall(outdir)                # 解压所有文件到 outdir
        files = z.namelist()                # 获取当前 zip 里的所有文件名
        inner_zips = []                     # 存放“里面的 zip 文件名”
        for f in files:                     # 遍历文件名
            p = os.path.join(outdir,f)      # 把文件名和路径拼接一下
            t = sniff_format(p)
            if t in ARCH_EXTS:
                inner_zips.append(p)
        return inner_zips

def extract_7z(filename,outdir):
    with py7zr.SevenZipFile(filename, 'r') as z:
        z.extractall(outdir)
        files = z.getnames()

        inner_zips = []
        for f in files:
            p = os.path.join(outdir,f)
            t = sniff_format(p)
            if t in ARCH_EXTS:
                inner_zips.append(p)
        return inner_zips

# 写一个安全的输出名生成器：没后缀就加 .out，避免覆盖源文件。
def safe_outpath(filename, outdir, default_suffix='.out'):
    base = os.path.basename(filename)
    stem, ext = os.path.splitext(base)
    if not ext:  # 没有后缀，避免与输入同名
        stem += default_suffix
    return os.path.join(outdir, stem)

def extract_gz(filename,outdir):  #wacky_list/99
    outpath = safe_outpath(filename,outdir)
    with gzip.open(filename,'rb') as fin:
        with open(outpath,'wb') as fout:
            shutil.copyfileobj(fin,fout)

    return outpath

def extract_bz2(filename, outdir):
    outpath = safe_outpath(filename, outdir)
    with bz2.open(filename,'rb') as fin, open(outpath,'wb') as fout:
        shutil.copyfileobj(fin, fout)
    return outpath


def extract_xz(filename, outdir):
    outpath = safe_outpath(filename, outdir)
    with lzma.open(filename,'rb') as fin, open(outpath,'wb') as fout:
        shutil.copyfileobj(fin, fout)
    return outpath



def sniff_format(filename):
    if os.path.isdir(filename):
        return None
    with open(filename, 'rb') as f:
        sig = f.read(6)
    if sig.startswith(b'PK'):
        return '.zip'
    if sig.startswith(b'\x1f\x8b'):
        return '.gz'
    if sig.startswith(b'BZh'):
        return '.bz2'
    if sig.startswith(b'\xfd7zXZ'):
        return '.xz'
    if sig.startswith(b'7z\xbc\xaf\x27\x1c'):
        return '.7z'
    return None


while True:
    type_file = sniff_format(name)
    _, ext_guess = os.path.splitext(name)
    ext = (type_file or ext_guess or '').lower()
    if ext == '.zip':
        inner_zips=extract_zip(name,outdir)
        if not inner_zips:  # 空列表 [] 会触发 True
            break  # 没有子 zip，就结束循环
        name = inner_zips[0]
    elif ext == '.gz':
        name = extract_gz(name,outdir)
    elif ext =='.bz2':
        name = extract_bz2(name, outdir)
    elif ext =='.xz':
        name =extract_xz(name, outdir)
    elif ext =='.7z':
        inner_zips=extract_7z(name,outdir)
        if not inner_zips:  # 空列表 [] 会触发 True
            break  # 没有子 zip，就结束循环
        name = inner_zips[0]
    else:
        break

print("最终文件：", name)







